#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
静默更新系统 - 实现应用程序的静默更新功能
允许在不干扰用户体验的情况下自动下载和安装更新包
"""
import os
import time
import threading
import shutil
from datetime import datetime
import json
import subprocess
import sys

# 导入项目模块
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from utils import Logger
from utils.file_utils import FileUtils
from utils.auto_update.update_downloader import UpdateDownloader
from utils.auto_update.update_installer import UpdateInstaller
from utils.auto_update.config_manager import UpdateConfigManager

class SilentUpdater:
    """静默更新系统核心类"""
    def __init__(self):
        """初始化静默更新系统"""
        self.file_utils = FileUtils()
        self.update_config = UpdateConfigManager()
        self.downloader = UpdateDownloader()
        self.installer = UpdateInstaller()
        
        # 线程锁，确保更新操作的线程安全
        self.update_lock = threading.Lock()
        
        # 静默更新状态标志
        self.is_updating = False
        
        # 加载静默更新配置
        self.config = self.update_config.config
        
        Logger.log_info("静默更新系统初始化完成")
    
    def check_silent_update_allowed(self):
        """检查是否允许静默更新"""
        # 检查配置中是否启用了静默更新
        if not self.config.get("silent_update_enabled", False):
            Logger.log_info("静默更新未在配置中启用")
            return False
        
        # 检查是否在允许的时间窗口内
        if not self._is_within_update_window():
            self.logger.log_info("当前不在允许的静默更新时间窗口内")
            return False
        
        # 检查系统资源使用情况
        if not self._check_system_resources():
            self.logger.log_info("系统资源不足，暂时不进行静默更新")
            return False
        
        # 检查上次静默更新的时间间隔
        if not self._check_update_interval():
            self.logger.log_info("距离上次静默更新的时间间隔不足")
            return False
        
        return True
    
    def _is_within_update_window(self):
        """检查当前时间是否在允许的静默更新时间窗口内"""
        # 获取配置的更新窗口时间
        update_window_start = self.config.get("silent_update_window_start", "22:00")
        update_window_end = self.config.get("silent_update_window_end", "06:00")
        
        # 转换时间格式
        try:
            start_hour, start_minute = map(int, update_window_start.split(":"))
            end_hour, end_minute = map(int, update_window_end.split(":"))
            
            # 获取当前时间
            now = datetime.now()
            current_time = now.hour * 60 + now.minute
            start_time = start_hour * 60 + start_minute
            end_time = end_hour * 60 + end_minute
            
            # 检查是否在时间窗口内（考虑跨天的情况）
            if start_time < end_time:
                return start_time <= current_time <= end_time
            else:
                return current_time >= start_time or current_time <= end_time
        except Exception as e:
            self.logger.log_error(f"检查静默更新时间窗口失败: {str(e)}")
            # 如果配置错误，默认允许更新
            return True
    
    def _check_system_resources(self):
        """检查系统资源使用情况，确保有足够的资源进行更新"""
        # 这里实现简化版本，实际项目中可以使用psutil等库进行更详细的资源检查
        try:
            # 检查可用磁盘空间
            download_dir = self.downloader.get_download_directory()
            free_space = self.file_utils.get_free_disk_space(download_dir)
            min_free_space = self.config.get("min_free_space_mb", 500)
            
            if free_space < min_free_space:
                self.logger.log_warning(f"可用磁盘空间不足: {free_space}MB < {min_free_space}MB")
                return False
            
            return True
        except Exception as e:
            self.logger.log_error(f"检查系统资源失败: {str(e)}")
            # 如果检查失败，默认允许更新
            return True
    
    def _check_update_interval(self):
        """检查距离上次静默更新的时间间隔是否满足要求"""
        try:
            # 获取上次静默更新的时间
            last_update_time = self.config.get("last_silent_update_time", 0)
            min_interval_hours = self.config.get("min_update_interval_hours", 24)
            
            # 计算当前时间与上次更新时间的差值（小时）
            current_time = int(time.time())
            time_diff_hours = (current_time - last_update_time) / 3600
            
            # 检查是否满足最小时间间隔要求
            return time_diff_hours >= min_interval_hours or last_update_time == 0
        except Exception as e:
            self.logger.log_error(f"检查更新时间间隔失败: {str(e)}")
            # 如果检查失败，默认允许更新
            return True
    
    def perform_silent_update(self, version_info=None):
        """执行静默更新操作"""
        # 使用线程锁确保更新操作的线程安全
        with self.update_lock:
            if self.is_updating:
                self.logger.log_info("静默更新已在进行中，跳过本次请求")
                return False, "静默更新已在进行中"
            
            self.is_updating = True
        
        try:
            # 检查是否允许静默更新
            if not self.check_silent_update_allowed():
                return False, "当前不满足静默更新条件"
            
            # 如果没有提供版本信息，则获取最新版本信息
            if version_info is None:
                self.logger.log_info("开始获取最新版本信息")
                # 这里应该调用版本检查器获取最新版本信息
                # 简化实现，使用模拟数据
                version_info = {
                    "version": "1.1.0",
                    "update_type": "minor",
                    "file_size": "20MB",
                    "release_date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "download_url": "https://example.com/updates/v1.1.0/update_package.zip",
                    "md5_checksum": "d41d8cd98f00b204e9800998ecf8427e"
                }
                
            self.logger.log_info(f"准备静默更新到版本: {version_info['version']}")
            
            # 下载更新包
            download_result = self.downloader.download_update(
                version_info["download_url"], 
                version_info["md5_checksum"]
            )
            
            if not download_result["success"]:
                self.logger.log_error(f"静默更新下载失败: {download_result['message']}")
                return False, download_result["message"]
            
            # 安装更新包
            install_result = self.installer.install_update(
                download_result["file_path"],
                silent_mode=True  # 静默模式安装
            )
            
            if not install_result["success"]:
                self.logger.log_error(f"静默更新安装失败: {install_result['message']}")
                return False, install_result["message"]
            
            # 更新配置中的上次静默更新时间
            self.config["last_silent_update_time"] = int(time.time())
            self.config["last_installed_version"] = version_info["version"]
            self.update_config.save_config(self.config)
            
            self.logger.log_info(f"静默更新成功，已更新到版本: {version_info['version']}")
            
            # 如果配置了更新后自动重启
            if self.config.get("auto_restart_after_update", False):
                self.logger.log_info("准备在静默更新后重启应用程序")
                self._schedule_restart()
            
            return True, f"静默更新成功，已更新到版本: {version_info['version']}"
            
        except Exception as e:
            self.logger.log_error(f"静默更新过程中发生错误: {str(e)}")
            return False, f"静默更新失败: {str(e)}"
        finally:
            self.is_updating = False
    
    def _schedule_restart(self):
        """安排应用程序在适当时机重启"""
        try:
            # 获取重启延迟时间（秒）
            restart_delay = self.config.get("restart_delay_seconds", 10)
            
            self.logger.log_info(f"将在{restart_delay}秒后重启应用程序")
            
            # 创建一个定时器，在指定延迟后重启应用程序
            def restart_app():
                try:
                    # 获取当前Python解释器路径和主脚本路径
                    python_exe = sys.executable
                    main_script = os.path.join(
                        os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
                        "main_window.py"
                    )
                    
                    self.logger.log_info(f"准备重启应用程序: {python_exe} {main_script}")
                    
                    # 启动新的应用程序进程
                    subprocess.Popen([python_exe, main_script])
                    
                    # 退出当前进程
                    sys.exit(0)
                except Exception as e:
                    self.logger.log_error(f"重启应用程序失败: {str(e)}")
            
            # 设置定时器
            timer = threading.Timer(restart_delay, restart_app)
            timer.daemon = True
            timer.start()
            
        except Exception as e:
            self.logger.log_error(f"安排应用程序重启失败: {str(e)}")
    
    def cleanup(self):
        """清理静默更新系统资源"""
        self.logger.log_info("静默更新系统资源清理完成")

# 示例用法
if __name__ == "__main__":
    try:
        silent_updater = SilentUpdater()
        result, message = silent_updater.perform_silent_update()
        print(f"静默更新结果: {result}, 消息: {message}")
    except Exception as e:
        print(f"示例执行出错: {str(e)}")